package com.demo.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.demo.mapper.StudentMapper;
import com.demo.mapper.ScheduleMapper;
import com.demo.mapper.ClazzMapper;
import com.demo.mapper.TeacherMapper;
import com.demo.mapper.TeacherPreferenceMapper;
import com.demo.pojo.dto.ScheduleListDTO;
import com.demo.pojo.entity.Student;
import com.demo.pojo.entity.Clazz;
import com.demo.pojo.entity.Teacher;
import com.demo.pojo.entity.TeacherPreference;
import com.demo.service.TeacherUserService;
import com.demo.service.ScheduleService;
import java.util.Date;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 教师用户服务实现类
 */
@Service
public class TeacherUserServiceImpl implements TeacherUserService {
    
    @Autowired
    private TeacherMapper teacherMapper;
    
    @Autowired
    private TeacherPreferenceMapper teacherPreferenceMapper;
    
    @Autowired
    private ScheduleService scheduleService;
    
    @Autowired
    private ScheduleMapper scheduleMapper;
    
    @Autowired
    private StudentMapper studentMapper;
    
    @Autowired
    private ClazzMapper clazzMapper;
    
    @Override
    public Teacher teacherLogin(String teNo, String password) {
        if (teNo == null || teNo.trim().isEmpty()) {
            throw new RuntimeException("教师工号不能为空");
        }
        
        if (password == null || password.trim().isEmpty()) {
            throw new RuntimeException("密码不能为空");
        }
        
        // 使用BINARY确保工号区分大小写（安全性要求）
        QueryWrapper<Teacher> queryWrapper = new QueryWrapper<>();
        queryWrapper.apply("BINARY te_no = {0}", teNo);
        Teacher teacher = teacherMapper.selectOne(queryWrapper);
        
        if (teacher == null) {
            throw new RuntimeException("教师工号不存在");
        }
        
        // 验证身份证后六位
        String idCard = teacher.getTeIdCard();
        if (idCard == null || idCard.length() < 6) {
            throw new RuntimeException("教师身份证信息不完整");
        }
        
        String lastSixDigits = idCard.substring(idCard.length() - 6);
        if (!password.equals(lastSixDigits)) {
            throw new RuntimeException("密码错误，请输入身份证后六位");
        }
        
        return teacher;
    }
    
    @Override
    public Teacher getTeacherInfo(Long teacherId) {
        return teacherMapper.selectById(teacherId);
    }
    
    @Override
    public boolean updateTeacherInfo(Teacher teacher) {
        return teacherMapper.updateById(teacher) > 0;
    }
    
    @Override
    public List<ScheduleListDTO> getTeacherSchedule(Long teacherId, String semester) {
        return scheduleService.getTeacherSchedule(teacherId, semester);
    }
    
    @Override
    public List<ScheduleListDTO> getTeacherWeekSchedule(Long teacherId, String semester, Integer weekNo) {
        // 这里需要根据周次过滤课表
        List<ScheduleListDTO> allSchedules = scheduleService.getTeacherSchedule(teacherId, semester);
        // 简化实现，实际需要根据时间段表查询周次
        return allSchedules;
    }
    
    @Override
    public List<ScheduleListDTO> getTeacherTodaySchedule(Long teacherId, String semester, Integer weekNo, Integer dayOfWeek) {
        // 这里需要根据星期几过滤课表
        List<ScheduleListDTO> allSchedules = scheduleService.getTeacherSchedule(teacherId, semester);
        // 简化实现，实际需要根据时间段表查询星期几
        return allSchedules;
    }
    
    @Override
    public boolean applyScheduleChange(Long scheduleId, String reason, Long newTimeSlotId, Long newClassroomId) {
        // 调课申请逻辑
        // 这里需要创建调课申请记录，等待管理员审批
        return true; // 简化实现
    }
    
    @Override
    public Map<String, Object> getTeacherWorkloadStats(Long teacherId, String semester) {
        try {
            System.out.println("===== 获取教师工作量统计 =====");
            System.out.println("教师ID: " + teacherId + ", 学期: " + semester);
            
            // 1. 获取教师的所有排课（先尝试指定学期，如果没数据则获取全部）
            List<ScheduleListDTO> schedules = scheduleService.getTeacherSchedule(teacherId, semester);
            System.out.println("指定学期排课数量: " + schedules.size());
            
            // 如果指定学期没有数据，尝试获取所有学期的数据
            if (schedules.isEmpty() && semester != null && !semester.isEmpty()) {
                System.out.println("指定学期无数据，尝试获取所有学期...");
                schedules = scheduleService.getTeacherSchedule(teacherId, null);
                System.out.println("所有学期排课数量: " + schedules.size());
            }
            
            System.out.println("最终使用排课数量: " + schedules.size());
            
            Map<String, Object> stats = new HashMap<>();
            
            if (schedules == null || schedules.isEmpty()) {
                stats.put("totalHours", 0);
                stats.put("courseCount", 0);
                stats.put("studentCount", 0);
                stats.put("avgWeeklyHours", 0);
                stats.put("courseDetails", new ArrayList<>());
                stats.put("weeklyDistribution", new ArrayList<>());
                return stats;
            }
            
            // 2. 统计不同的课程（按课程ID去重）
            Set<Long> uniqueCourses = new HashSet<>();
            for (ScheduleListDTO schedule : schedules) {
                if (schedule.getCourseId() != null) {
                    uniqueCourses.add(schedule.getCourseId());
                }
            }
            int courseCount = uniqueCourses.size();
            System.out.println("不同课程数: " + courseCount);
            
            // 3. 计算总课时（每个排课默认2学时，一周重复16次）
            int totalHours = schedules.size() * 2 * 16;
            System.out.println("总课时: " + totalHours);
            
            // 4. 统计学生人数（通过班级）
            Set<Long> uniqueClazzes = new HashSet<>();
            for (ScheduleListDTO schedule : schedules) {
                if (schedule.getClazzId() != null) {
                    uniqueClazzes.add(schedule.getClazzId());
                }
            }
            
            int studentCount = 0;
            for (Long clazzId : uniqueClazzes) {
                QueryWrapper<Student> wrapper = new QueryWrapper<>();
                wrapper.eq("clazz_id", clazzId);
                studentCount += studentMapper.selectCount(wrapper);
            }
            System.out.println("学生总数: " + studentCount);
            
            // 5. 计算平均周课时（16周学期）
            double avgWeeklyHours = schedules.size() * 2.0;
            System.out.println("平均周课时: " + avgWeeklyHours);
            
            // 6. 构建课程详细信息列表
            List<Map<String, Object>> courseDetails = new ArrayList<>();
            Map<Long, List<ScheduleListDTO>> courseScheduleMap = new HashMap<>();
            
            // 按课程分组
            for (ScheduleListDTO schedule : schedules) {
                Long courseId = schedule.getCourseId();
                courseScheduleMap.computeIfAbsent(courseId, k -> new ArrayList<>()).add(schedule);
            }
            
            for (Map.Entry<Long, List<ScheduleListDTO>> entry : courseScheduleMap.entrySet()) {
                List<ScheduleListDTO> courseSchedules = entry.getValue();
                ScheduleListDTO first = courseSchedules.get(0);
                
                Map<String, Object> detail = new HashMap<>();
                detail.put("courseName", first.getCourseName());
                detail.put("className", first.getClazzName());
                detail.put("courseType", "必修"); // 默认必修
                detail.put("credits", 4); // 默认4学分
                detail.put("totalHours", courseSchedules.size() * 2 * 16);
                detail.put("completedHours", courseSchedules.size() * 2 * 8); // 假设完成一半
                detail.put("remainingHours", courseSchedules.size() * 2 * 8);
                
                // 统计该课程的学生数
                int classStudentCount = 0;
                if (first.getClazzId() != null) {
                    QueryWrapper<Student> wrapper = new QueryWrapper<>();
                    wrapper.eq("clazz_id", first.getClazzId());
                    classStudentCount = (int) studentMapper.selectCount(wrapper).longValue();
                }
                detail.put("studentCount", classStudentCount);
                detail.put("progress", 50); // 默认50%进度
                
                courseDetails.add(detail);
            }
            
            // 7. 构建周课时分布（16周）
            List<Map<String, Object>> weeklyDistribution = new ArrayList<>();
            for (int week = 1; week <= 16; week++) {
                Map<String, Object> weekData = new HashMap<>();
                weekData.put("week", week);
                weekData.put("hours", (int) avgWeeklyHours);
                weeklyDistribution.add(weekData);
            }
            
            // 8. 组装结果
            stats.put("totalHours", totalHours);
            stats.put("courseCount", courseCount);
            stats.put("studentCount", studentCount);
            stats.put("avgWeeklyHours", (int) avgWeeklyHours);
            stats.put("courseDetails", courseDetails);
            stats.put("weeklyDistribution", weeklyDistribution);
            
            System.out.println("统计完成!");
            return stats;
            
        } catch (Exception e) {
            System.err.println("统计工作量失败: " + e.getMessage());
            e.printStackTrace();
            throw new RuntimeException("统计工作量失败: " + e.getMessage(), e);
        }
    }
    
    @Override
    public Map<String, Object> getTeacherTimePreference(Long teacherId) {
        QueryWrapper<TeacherPreference> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("teacher_id", teacherId)
                   .eq("is_enabled", 1);
        List<TeacherPreference> preferences = teacherPreferenceMapper.selectList(queryWrapper);
        
        Map<String, Object> result = new HashMap<>();
        for (TeacherPreference preference : preferences) {
            result.put(preference.getPreferenceType(), preference.getPreferenceContent());
        }
        
        return result;
    }
    
    @Override
    public boolean setTeacherTimePreference(Long teacherId, Map<String, Object> preferences) {
        try {
            // 删除现有偏好
            QueryWrapper<TeacherPreference> deleteWrapper = new QueryWrapper<>();
            deleteWrapper.eq("teacher_id", teacherId);
            teacherPreferenceMapper.delete(deleteWrapper);
            
            // 添加新偏好
            for (Map.Entry<String, Object> entry : preferences.entrySet()) {
                TeacherPreference preference = new TeacherPreference();
                preference.setTeacherId(teacherId);
                preference.setPreferenceType(entry.getKey());
                preference.setPreferenceContent(entry.getValue().toString());
                preference.setWeight(5);
                preference.setIsEnabled(1);
                preference.setCreateTime(new Date());
                preference.setUpdateTime(new Date());
                teacherPreferenceMapper.insert(preference);
            }
            
            return true;
        } catch (Exception e) {
            return false;
        }
    }
    
    @Override
    public List<Map<String, Object>> getTeacherStudents(Long teacherId, String semester) {
        List<Map<String, Object>> result = new ArrayList<>();
        
        try {
            System.out.println("Service层 - 开始查询教师学生");
            System.out.println("教师ID: " + teacherId + ", 学期: " + semester);
            
            // 直接通过 teacher_id 查询学生
            QueryWrapper<Student> studentWrapper = new QueryWrapper<>();
            studentWrapper.eq("teacher_id", teacherId);
            List<Student> students = studentMapper.selectList(studentWrapper);
            
            System.out.println("查询到学生数量: " + (students != null ? students.size() : 0));
            
            if (students == null || students.isEmpty()) {
                System.out.println("该教师没有关联的学生");
                return result;
            }
            
            // 构建学生信息（包含班级信息）
            for (Student student : students) {
                Map<String, Object> studentInfo = new HashMap<>();
                studentInfo.put("studentId", student.getStudentId());
                studentInfo.put("stuNo", student.getStuNo());
                studentInfo.put("stuName", student.getStuName());
                studentInfo.put("stuAge", student.getStuAge());
                studentInfo.put("stuSex", student.getStuSex());
                studentInfo.put("stuDept", student.getStuDept());
                studentInfo.put("stuPhone", student.getStuPhone());
                studentInfo.put("stuEmail", student.getStuEmail());
                studentInfo.put("stuQq", student.getStuQq());
                studentInfo.put("stuRemark", student.getStuRemark());
                
                // 获取班级信息
                if (student.getClazzId() != null) {
                    Clazz clazz = clazzMapper.selectById(student.getClazzId());
                    if (clazz != null) {
                        studentInfo.put("clazzId", clazz.getClazzId());
                        studentInfo.put("clazzName", clazz.getClazzName());
                        studentInfo.put("grade", clazz.getGrade());
                        studentInfo.put("dept", clazz.getDept());
                    } else {
                        studentInfo.put("clazzId", student.getClazzId());
                        studentInfo.put("clazzName", "未知班级");
                        studentInfo.put("grade", "");
                        studentInfo.put("dept", student.getStuDept());
                    }
                } else {
                    studentInfo.put("clazzId", null);
                    studentInfo.put("clazzName", "未分配班级");
                    studentInfo.put("grade", "");
                    studentInfo.put("dept", student.getStuDept());
                }
                
                result.add(studentInfo);
            }
            
            System.out.println("最终返回学生总数: " + result.size());
            return result;
        } catch (Exception e) {
            System.err.println("Service层异常：");
            e.printStackTrace();
            throw new RuntimeException("查询教师学生失败: " + e.getMessage(), e);
        }
    }
}


